<?php


namespace App\Models\CacheModel;


use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use App\Models\Api\BaseCache;
use think\Cache;
use think\Log;
use AstroTool\Cache\CacheManage;

/**
 * 微信用户信息
 * Class Wechat
 * @package App\Models\CacheModel
 */
class Wechat extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_wechat';
    protected $cacheModel = 'wechat.wechat';
    const WECHAT_ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token';
    const WECHAT_GET_USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo';

    public function SaveData($data)
    {
        $res = Cache::get($data['unionid']);
        if ($res)
        {
            throw new ApiException('当前账号已注册，请勿重复操作');
        }
        Cache::set($data['unionid'], 1, 2);
        try
        {
            $this->save($data);
        }
        catch (\Exception $e)
        {
            Log::write('添加用户微信信息失败：' . $e->getMessage(), 'error', true);
            return false;
        }
        return true;
    }

    /**
     * 更新用户微信信息
     * @param $data
     * @param $map
     * @return bool
     * @throws \Exception
     */
    public function UpdateData($data, $map, $uid, $unionid)
    {
        try
        {
            $this->where($map)->update($data);
        }
        catch (\Exception $e)
        {
            Log::write('更新用户微信信息失败：' . $e->getMessage(), 'error', true);
            return false;
        }
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $unionid . '-1')->rmCache();
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . '-2')->rmCache();
        return true;
    }

    /**
     * 删除用户微信信息
     * @param $data
     * @param $map
     * @return bool
     * @throws \Exception
     */
    public function DelData($uid)
    {
        $wechat_user = $this->getWechatInfo($uid, 2);
        if ($wechat_user)
        {
            try
            {
                $this->where(['uid' => $uid])->delete();
            }
            catch (\Exception $e)
            {
                Log::write('删除用户微信信息失败：' . $e->getMessage(), 'error', true);
                return false;
            }
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $wechat_user['unionid'] . '-1')->rmCache();
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . '-2')->rmCache();
            return true;
        }
        return true;
    }

    /**
     * 微信登录
     * @param $param
     * @return array|Json
     * @throws ApiException
     * @throws GuzzleException
     * @throws Exception
     */
    public function WechatInfo($param)
    {
        if (!array_key_exists('code', $param))
        {
            throw new ApiException('用户code不存在,请重新登录!', 200, 0);
        }
        $access_token_url = self::WECHAT_ACCESS_TOKEN_URL . '?appid=' . config('wechat.wechat_appid') . '&secret=' . config('wechat.wechat_appsecret')
            . '&code=' . $param['code'] . '&grant_type=authorization_code';

        $access_token = Util::curl_get($access_token_url);
        $access_token = json_decode($access_token, true);
        if (isset($access_token['errcode']))
        {
            throw new ApiException($access_token['errcode'] . ':' . $access_token['errmsg'], 200, 0);
        }
        $userinfo_url = self::WECHAT_GET_USERINFO_URL . "?access_token={$access_token['access_token']}&openid={$access_token['openid']}&lang=zh_CN";
        $user_info = Util::curl_get($userinfo_url);
        $user_info = json_decode($user_info, true);
        if (isset($user_info['errcode']))
        {
            throw new ApiException($user_info['errcode'] . ':' . $user_info['errmsg'], 200, 0);
        }
        if ($user_info)
        {
            return $user_info;
        }
        throw new ApiException('微信授权失败', 200, 0);
    }

    /**
     * 缓存获取用户微信信息
     * @param $param
     * @param int $type 1=>$unionid,2=>uid
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getWechatInfo($param, $type = 1)
    {
        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $param . '-' . $type)->getDataAndSet(function () use ($param, $type)
        {
            return $this->getWechatInfoFromDms($param, $type);
        });

        if ($data && $data['forbidden'] == 1)
        {
            throw new ApiException('该账号禁止登录', 200, 0);
        }
        return $data;
    }

    /**
     * 数据库获取用户微信信息
     * @param $param
     * @param int $type
     * @return array|mixed
     */
    public function getWechatInfoFromDms($param, $type = 1)
    {
        switch ($type)
        {
            case 1:
                $where = ['unionid' => $param];
                break;
            case 2:
                $where = ['uid' => $param];
                break;
            default:
                return [];
                break;
        }
        try
        {
            $data = $this->alias('w')->join('wechat_backup_07_18_14_43_00.app_user u', 'w.uid=u.id')
                ->where($where)->column('w.uid,w.nickname,w.headimgurl,w.sex,w.unionid,w.openid,w.city,w.province,w.country,w.scope,w.expires_in,w.access_token,w.refresh_token,w.create_time,u.forbidden,u.has_self_recode,u.avatar');
            $data = current($data);
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }
}
